package cn.lix.sc.rpc.impl.common.utils;

import cn.lix.sc.rpc.impl.common.exception.SystemException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Date;


public class MethodParametersJsonConvertor {


    public static Object[] convert(String param, Class[] types) throws Exception {
        if (StringUtils.isEmpty(param) || types.length < 1) {
            return new Object[0];
        }
        Object[] parameters = new Object[types.length];
        JsonNode array = new ObjectMapper().readTree(param);

        if (!array.isArray() || array.size() != types.length) {
            throw SystemException.error("方法参数不一致");
        }
        
        for (int i = 0; i < types.length; i++) {
            JsonNode node = array.get(i);
            parameters[i] = convertJsonNode(node, types[i]);
        }
        return parameters;
    }

    private static Object convertJsonNode(JsonNode node, Class<?> type) throws Exception {
        if (node == null || node.isNull()) {
            return null;
        }
        
        if (type == String.class) {
            return node.asText();
        } else if (type == Date.class) {
            return new Date(node.asLong());
        } else if (type == Byte.class || type == byte.class) {
            return (byte) node.asInt();
        } else if (type == Short.class || type == short.class) {
            return (short) node.asInt();
        } else if (type == Integer.class || type == int.class) {
            return node.asInt();
        } else if (type == Long.class || type == long.class) {
            return node.asLong();
        } else if (type == Double.class || type == double.class) {
            return node.asDouble();
        } else if (type == Float.class || type == float.class) {
            return (float) node.asDouble();
        } else if (type == Boolean.class || type == boolean.class) {
            return node.asBoolean();
        } else {
            return new ObjectMapper().convertValue(node, type);
        }
    }

    public static Object convert(String param, Class<?> type) throws Exception {
        if (StringUtils.isEmpty(param)) {
            return null;
        }
        return JsonUtil.string2Obj(param, type);
    }

    public static String getMethodKey(String className, Method method){
        String key = className.concat("#").concat(method.getName());
        Class<?>[] types = method.getParameterTypes();
        for (Class<?> type : types) {
            key = key.concat("_").concat(type.getSimpleName());
        }
        return key;
    }

}
